﻿using SIG.Basic.Extensions;
using SIG.Infrastructure.Cache;
using SIG.Infrastructure.Configs;
using SIG.Infrastructure.Logging;
using SIG.Model;
using SIG.Repository;
using SIG.Resources;
using SIG.Resources.Admin;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace SIG.Service
{
    public class PageService: EntityService<Page>, IPageService
    {
     
        private readonly IPageRepository _pageRepository;
        private readonly ILoggingService _loggingService;
        private readonly ICacheService _cacheProvider;

        public PageService(IPageRepository pageRepository, ILoggingService loggingService, ICacheService cacheProvider)
            : base( pageRepository, cacheProvider, loggingService)
        {
           
            _pageRepository = pageRepository;
            _loggingService = loggingService;
            _cacheProvider = cacheProvider;
        }

        public Page GetPageBySeoName(string seoName)
        {
            var key = $"{EntityNames.Page}_SeoName_{seoName}";            

            if (!SettingsManager.Page.EnableCaching)
                return _pageRepository.GetFirstOrDefault(p => p.SeoName == seoName);
          
            if (_cacheProvider.IsSet(key))
            {
                return (Page)_cacheProvider.Get(key);              
            }

            Page page = _pageRepository.GetFirstOrDefault(p => p.SeoName == seoName);
            _cacheProvider.Set(key, page, SettingsManager.Page.CacheDuration);

            return page;

        }

        public List<Page> GetPagedElements(int pageIndex, int pageSize, string keyword, out int totalCount)
        {

            //get list count
            var keyCount = $"{EntityNames.Page}_ListCount_{keyword}";

            var totalIQuery = _pageRepository.GetAllElements();
            if (!string.IsNullOrEmpty(keyword))
                totalIQuery = totalIQuery.Where(g => g.Body.Contains(keyword));


            if (SettingsManager.Store.EnableCaching)
            {
                if (_cacheProvider.IsSet(keyCount))
                {
                    totalCount = (int)_cacheProvider.Get(keyCount);
                }
                else
                {
                    totalCount = totalIQuery.Count();
                    _cacheProvider.Set(keyCount, totalCount, SettingsManager.Store.CacheDuration);
                }
            }
            else
            {
                totalCount = totalIQuery.Count();
            }


            //get list
            var key = $"{EntityNames.Page}_List_{pageIndex}_{pageSize}_{keyword}";

            List<Page> pages;
            Expression<Func<Page, bool>> filter = g => true;
            Expression<Func<Page, bool>> filterByKeyword = g => g.Body.Contains(keyword);


            if (!string.IsNullOrEmpty(keyword))
                filter = filter.AndAlso(filterByKeyword);



            if (SettingsManager.Store.EnableCaching)
            {
                if (_cacheProvider.IsSet(key))
                {
                    pages = (List<Page>)_cacheProvider.Get(key);

                }
                else
                {
                    pages = _pageRepository.GetPagedElements(pageIndex, pageSize, (c => c.CreatedDate), filter, false).ToList();
                    _cacheProvider.Set(key, pages, SettingsManager.Store.CacheDuration);
                }
            }
            else
            {
                pages = _pageRepository.GetPagedElements(pageIndex, pageSize, (c => c.CreatedDate), filter, false).ToList();
            }

            return pages;

        }


        public int SearchPagesCount(string Title)
        {
            var key = $"{EntityNames.Page}s_SearchCount_{Title}";  
           
            if (!SettingsManager.Page.EnableCaching)
                return _pageRepository.GetFilteredElements(p => p.Title.Contains(Title)).Count();

            if (_cacheProvider.IsSet(key))
            {
                return (int)_cacheProvider.Get(key);
               
            }

            int pagesCount = _pageRepository.GetFilteredElements(p=>p.Title.Contains(Title)).Count();
            _cacheProvider.Set(key, pagesCount, SettingsManager.Page.CacheDuration);
            return pagesCount;


        }


        public IList<Page> SearchPages(int pageIndex, int pageSize, string Title)
        {
            var key = $"{EntityNames.Page}s_Search_{pageIndex}_{pageSize}_{Title}";         

         
            if (!SettingsManager.Page.EnableCaching)
            {
                if (!string.IsNullOrEmpty(Title))
                {
                    return _pageRepository.GetPagedElements(pageIndex, pageSize, (p => p.Id), (p => p.Title.Contains(Title)), true).ToList();
                }
                return _pageRepository.GetPagedElements(pageIndex, pageSize, (p => p.Id), true).ToList();
              
            }
                
          
            if (_cacheProvider.IsSet(key))
            {
                return (List<Page>)_cacheProvider.Get(key);
            }



            IList<Page> pages = string.IsNullOrEmpty(Title)? 
                _pageRepository.GetPagedElements(pageIndex, pageSize, (p => p.Id), true).ToList() : 
                _pageRepository.GetPagedElements(pageIndex, pageSize, (p => p.Id), (p=>p.Title.Contains(Title)),true).ToList();

            _cacheProvider.Set(key, pages, SettingsManager.Page.CacheDuration);
            return pages;


        }


        public int ActivePagesCount()
        {
            var key = $"{EntityNames.Page}s_ActiveCount";

            if (!SettingsManager.Page.EnableCaching)
                return _pageRepository.GetFilteredElements(p=>p.Active).Count();           

            if (_cacheProvider.IsSet(key))            
                return (int)_cacheProvider.Get(key);           

            int pagesCount = _pageRepository.GetFilteredElements(p => p.Active).Count();
            _cacheProvider.Set(key, pagesCount, SettingsManager.Page.CacheDuration);         
            return pagesCount;
        }


        public IList<Page> GetActivePages(int pageIndex, int pageSize)
        {
            var key = $"{EntityNames.Page}s_Active_{pageIndex}_{pageSize}";

            if (!SettingsManager.Page.EnableCaching)
                return _pageRepository.GetPagedElements(pageIndex, pageSize, (p => p.Id), (p => p.Active),true).ToList();          

            if (_cacheProvider.IsSet(key))           
                return (List<Page>)_cacheProvider.Get(key);           
          
            List<Page> pages = _pageRepository.GetPagedElements(pageIndex, pageSize, (p => p.Id), (p => p.Active), true).ToList();
            _cacheProvider.Set(key, pages, SettingsManager.Page.CacheDuration);
           

            return pages;
        }

    }
}
